package com.niepan.common.utils.logs;
import org.apache.log4j.Logger;


/**
 * @author weifuqiang
 * @date 2023/3/2
 *
 * 首先将LogUtil的构造函数私有化，这样就无法使用new关键字来创建LogUtil的实例了。
 * 然后使用一个sLogUtil私有静态变量来保存实例，并提供一个公有的getInstance方法用于获取LogUtil的实例，
 * 在这个方法里面判断如果 sLogUtil为空，就new出一个新的LogUtil实例，
 * 否则就直接返回sLogUtil。
 * 这样就可以保证内存当中只会存在一个LogUtil的实例了。单例模式完工！
 */
public class LogUtils {
//    private static final String TAG = LogUtils.class.getCanonicalName(); // com.niepan.common.utils.logs.LogUtils
    public static final String TAG = LogUtils.class.getCanonicalName(); // com.niepan.common.utils.logs.LogUtils
    private static String className;
    private static String methodName;
    private static int lineNumber;
    // 是否开启debug模式

    private static boolean isDebug = true;

    static Logger logger = Logger.getLogger(new Throwable().getStackTrace()[1].getFileName()); // 打印出栈对象


    // 乐观锁
    private static volatile LogUtils logUtils;

    public static LogUtils getInstance() {
        if (logUtils == null) {
            synchronized (logUtils.getClass()) {
                logUtils = new LogUtils();
            }
        }
        return logUtils;
    }
    private  LogUtils() {

    }
    private static boolean isDebuggable() {
        return isDebug;
    }

    // 拼接 方法名+行号+log
    private static String createLog(String log) {
        // 线程安全的 动态字符串
        StringBuffer buffer = new StringBuffer();
        buffer.append("[");
        buffer.append(methodName);
        buffer.append(":");
        buffer.append(lineNumber);
        buffer.append("]");
        buffer.append(log);
        return buffer.toString();
    }

    private static void getMethodNames(StackTraceElement[] sElements){
        className = sElements[1].getClassName(); //类名
        methodName = sElements[1].getMethodName();//方法名
        lineNumber = sElements[1].getLineNumber();// 行号
//        for (StackTraceElement sElement : sElements) {
//            String fileName = sElement.getFileName();
//            System.out.println("fileName = " + fileName);
//            String className = sElement.getClassName();
//            System.out.println("className = " + className);
//            String methodName = sElement.getMethodName();
//            System.out.println("methodName = " + methodName);
//            int lineNumber = sElement.getLineNumber();
//            System.out.println("lineNumber = " + lineNumber);
//        }
    }


    public static void error(String message){
        getMethodNames(new Throwable().getStackTrace());
        logger.error("ERROR --- "+ "ClassName:  "+className +" - "+ "MethodName:   " + methodName +" - "+ "LineNumber:   "  + lineNumber +" - " + "Message:   "+ message);
    }


    public static void info(String message){
        getMethodNames(new Throwable().getStackTrace());
        logger.info("INFO --- "+ "ClassName:  "+className +" - "+ "MethodName:   " + methodName +" - "+ "LineNumber:   "  + lineNumber +" - " + "Message:   "+ message);
    }


    public static void debug(String message){
        if (!isDebuggable())
            return;
        getMethodNames(new Throwable().getStackTrace());
        logger.debug("DEBUG --- "+ "ClassName:  "+className +" - "+ "MethodName:   " + methodName +" - "+ "LineNumber:   "  + lineNumber +" - " + "Message:   "+ message);
    }


    public static void trace(String message){
        getMethodNames(new Throwable().getStackTrace());
        logger.trace("TRACE --- "+ "ClassName:  "+className +" - "+ "MethodName:   " + methodName +" - "+ "LineNumber:   "  + lineNumber +" - " + "Message:   "+ message);

    }


    public static void warn(String message){
        getMethodNames(new Throwable().getStackTrace());
        logger.warn("WARN --- "+ "ClassName:  "+className +" - "+ "MethodName:   " + methodName +" - "+ "LineNumber:   "  + lineNumber +" - " + "Message:   "+ message);
    }
}
